﻿using System;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;

namespace XBLMS.Utils
{
    public static class HttpClientUtils
    {
        public static async Task<JObject> GetOauthFile()
        {
            var filePath = PathUtils.Combine(AppDomain.CurrentDomain.BaseDirectory, Configuration.Constants.SsoConfigFileName);
            if (FileUtils.IsFileExists(filePath))
            {
                var json = await FileUtils.ReadTextAsync(filePath);
                JObject ssoConfig = JObject.Parse(json);
                return ssoConfig;
            }
           return null;
        }
        public static async Task<string> RedirectUri()
        {
            var oauthFile= await GetOauthFile();
            if (oauthFile != null)
            {
                var redirectUri = oauthFile["redirectUri"];
                if (redirectUri != null)
                {
                    return WebUtility.UrlEncode(redirectUri.ToString());
                }
            }
            return WebUtility.UrlEncode("http://learning.qifu.com/home/login");
        }
        public static async Task<string> AuthUri()
        {
            var oauthFile = await GetOauthFile();
            object authUri = null;
            if (oauthFile != null)
            {
                authUri = oauthFile["authUri"];
            }
            return authUri != null ? authUri.ToString() : "http://keycloak.qifu.com/realms/keyfil/protocol/openid-connect/auth";
        }
        public static async Task<string> TokenUri()
        {
            var oauthFile = await GetOauthFile();
            object tokenUri = null;
            if (oauthFile != null)
            {
                tokenUri = oauthFile["tokenUri"];
            }
            return tokenUri != null ? tokenUri.ToString() : "http://keycloak.qifu.com/realms/keyfil/protocol/openid-connect/token";
        }
        public static async Task<string> UserInfoUri()
        {
            var oauthFile = await GetOauthFile();
            object userInfoUri = null;
            if (oauthFile != null)
            {
                userInfoUri = oauthFile["userInfoUri"];
            }
            return userInfoUri != null ? userInfoUri.ToString() : "http://keycloak.qifu.com/realms/keyfil/protocol/openid-connect/userinfo";
        }

        public static async Task<string> GetStringAsync(string url)
        {
            return await GetStringAsync(url, Encoding.UTF8);
        }

        public static async Task<string> GetStringAsync(string url, Encoding encoding)
        {
            try
            {
                string html;

                if (encoding == Encoding.UTF8)
                {
                    using (var client = new HttpClient())
                    {
                        html = await client.GetStringAsync(url);
                    }
                }
                else
                {
                    using (var client = new HttpClient())
                    {
                        var bytes = await client.GetByteArrayAsync(url);
                        html = ConvertBytesToString(bytes, encoding);
                    }
                }

                return html;
            }
            catch (Exception ex)
            {
                throw new Exception($"页面地址“{url}”无法访问，{ex.Message}！");
            }
        }

        private static string ConvertBytesToString(byte[] bytes, Encoding encoding)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            var toEncoding = Encoding.UTF8;
            var toBytes = Encoding.Convert(encoding, toEncoding, bytes);
            return toEncoding.GetString(toBytes);
        }

        public static async Task<bool> DownloadAsync(string remoteUrl, string filePath)
        {
            try
            {
                DirectoryUtils.CreateDirectoryIfNotExists(filePath);
                FileUtils.DeleteFileIfExists(filePath);

                using (var client = new HttpClient())
                {
                    using (var stream = await client.GetStreamAsync(remoteUrl))
                    {
                        using (var fs = new FileStream(filePath, FileMode.CreateNew))
                        {
                            await stream.CopyToAsync(fs);
                        }
                    }
                }

                // using var client = new WebClient();
                // client.DownloadFile(remoteUrl, filePath);
            }
            catch (Exception ex)
            {
                throw new Exception($"页面地址“{remoteUrl}”无法访问，{ex.Message}！");
            }
            return true;
        }

        public static async Task<string> PostAccessToken(string code, string state)
        {
            HttpResponseMessage response = null;
            try
            {
                using (var client = new HttpClient())
                {
                    // 准备POST数据
                    string redirectUri = await RedirectUri();
                    string tokenUri = await TokenUri();
                    var content = new StringContent($"grant_type=authorization_code&client_id=lms&client_secret=VqxZ5UCzhaIHqwPI9H035xcPB7Jz8Ppj&code={code}&redirect_uri={redirectUri}", Encoding.UTF8, "application/x-www-form-urlencoded");
                    // 发送POST请求
                    response = await client.PostAsync(tokenUri, content);
                    //response.EnsureSuccessStatusCode(); // 确保响应状态码表示成功
                    string responseBody = await response.Content.ReadAsStringAsync();
                    return responseBody; 
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"PostAccessToken出错，code = {code} \n response = {response}，{ex.Message}！");
            }
        }

        public static async Task<string> PostUserInfo(string access_token)
        {
            try
            {
                using (var client = new HttpClient())
                {
                    // 准备POST数据
                    // 创建带有Bearer令牌的Authorization头
                    client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", access_token);
                    var content = new StringContent("", Encoding.UTF8, "application/x-www-form-urlencoded");
                    var userInfoUri = await UserInfoUri();
                    // 发送POST请求
                    HttpResponseMessage response = await client.PostAsync(userInfoUri, content);
                    //response.EnsureSuccessStatusCode(); // 确保响应状态码表示成功
                    string responseBody = await response.Content.ReadAsStringAsync();
                    return responseBody;
                }
            }
            catch (Exception ex)
            {
                throw new Exception($"PostUserInfo出错，access_token = {access_token}，{ex.Message}！");
            }
        }

        public static async Task<string> PostUserName(string code, string state)
        {
            string ai = null;
            JObject accessToken = null;
            string ui = null;
            JObject userInfo = null;
            try
            {
                ai = await PostAccessToken(code, state);
                accessToken = JObject.Parse(ai);

                ui = await PostUserInfo(accessToken["access_token"].ToString());

                userInfo = JObject.Parse(ui);
                return userInfo["preferred_username"].ToString();
            }
            catch (Exception ex)
            {
                throw new Exception($"PostUserName出错，code = {code}, ai = {ai}, ti = {accessToken}, ui = {ui}, uio = {userInfo}，{ex.Message}！");
            }
        }

        public class TokenInfo
        {
            public string Access_token { get; set; }
        }
        public class UserInfo
        {
            public string Preferred_username { get; set; }
        }
    }
}
